<?php

namespace app\services;

use app\api\validation\Activity;
use app\traits\Page;
use plugin\admin\app\model\BrandCustomized;
use plugin\admin\app\model\BrandCustomizedImage;
use plugin\admin\app\model\Goods;
use plugin\admin\app\model\GoodsActivity;
use plugin\admin\app\model\GoodsActivityRelation;
use plugin\admin\app\model\GoodsAttr;
use plugin\admin\app\model\GoodsAttrValue;
use plugin\admin\app\model\GoodsCategory;
use plugin\admin\app\model\GoodsCategoryRelation;
use plugin\admin\app\model\GoodsImage;
use plugin\admin\app\model\GoodsSKU;
use plugin\admin\app\model\GoodsSpec;
use plugin\admin\app\model\GoodsTag;
use plugin\admin\app\model\GoodsTagRelation;
use plugin\admin\app\model\Order;
use plugin\admin\app\model\OrderGoods;
use plugin\admin\app\model\UserCollect;
use plugin\admin\app\model\UserHistory;
use plugin\admin\app\model\UserLevelGoods;
use plugin\admin\app\model\UserProperty;
use support\Db;
use Webman\Event\Event;

class GoodsService
{
    public static function list($page, $length = 10, $order = ['id', 'desc'], $categoryId = 0, $keyword = '', $limitGoodsIds = [], $showActivityGoods = false, $isGift = null, $isRecommend = null, $isNormal = null)
    {
        $offset = ($page - 1) * $length;

        $query = Db::table('wa_goods', 'g')
            ->select(['g.id', 'g.thumb', 'g.name', 'g.price', 'g.sub_name', 'g.market_price', 'g.sale_count'])
            ->where('g.is_up', 1);

        $activity = GoodsActivityService::valid();
        $goodsIds = GoodsActivityService::getActivityGoodsIds($activity);

        if (!$showActivityGoods && $activity) {
            if ($activity['is_all_goods']) {
                return Page::wrap(0, $page, $length, []);
            } else {
                if (count($goodsIds) > 0) {
                    $query = $query->whereNotIn('g.id', $goodsIds);
                }
            }
        }

        if (!is_null($isGift)) {
            $query = $query->where('g.is_gift', $isGift);
        }

        if (!is_null($isRecommend)) {
            $query = $query->where('g.is_recommend', $isRecommend);
        }

        if (!is_null($isNormal)) {
            $query = $query->where('g.is_normal', $isNormal);
        }

        if ($categoryId) {
            $query->join(Db::raw('wa_goods_category_relations as gcr'), 'gcr.goods_id', '=', 'g.id', 'left');
            if (is_array($categoryId)) {
                $query->whereIn('gcr.category_id', $categoryId);
            } else {
                $query->where('gcr.category_id', $categoryId);
            }
        }

        if (count($limitGoodsIds) > 0) {
            $query->whereIn('g.id', $limitGoodsIds);
        }

        if ($keyword) {
            $query->where('g.name', 'like', "%{$keyword}%");
        }

        $totalCount = (clone $query)->count();
        $goodsList = (clone $query)->orderBy($order[0], $order[1])->offset($offset)->limit($length)->get()->toArray();

        if ($keyword && get_user_id()) {
            Event::dispatch('goods.search', $keyword);
        }

        foreach ($goodsList as $key=>$goods) {
            $goods = json_decode(json_encode($goods), true);
            $goods['thumb'] = full_url($goods['thumb']);

            if (isset($activity)) {
                if ($activity['type'] == GoodsActivity::DISCOUNT) {
                    if ($activity['is_all_goods'] || (isset($goodsIds) && count($goodsIds) && in_array($goods['id'], $goodsIds))) {
                        $goods['market_price'] = $goods['price'];
                        $goods['price'] = bcmul($goods['price'], bcdiv($activity['discount'], 100, 2), 2);
                    }
                } else {
                    if ($activity['is_all_goods'] || (isset($goodsIds) && count($goodsIds) && in_array($goods['id'], $goodsIds))) {
                        $goods['activity'] = $activity;
                    }
                }

            }

            $goodsList[$key] = $goods;
        }

        return Page::wrap($totalCount, $page, $length, $goodsList);
    }

    public static function detail($id)
    {

        $goodsInfo = Goods::select(['id', 'name', 'sub_name', 'price', 'market_price', 'stock', 'recharge_integral', 'register_integral', 'free_shipping', 'content', 'sale_count', 'type', 'model_id', 'is_gift'])->where('id', $id)->where('is_up', 1)->first();

        if (! $goodsInfo) {
            throw new \Exception('不存在的产品');
        }

        // 商品属性
        $goodsInfo = $goodsInfo->toArray();

        $goodsAttrValues = GoodsAttrValue::where('goods_id', $goodsInfo['id'])->get()->toArray();
        $goodsAttrValues = array_combine(
            array_column($goodsAttrValues, 'attr_id'),
            array_values($goodsAttrValues)
        );

        $attrIds = array_column($goodsAttrValues, 'attr_id');

        $goodsAttrs = GoodsAttr::whereIn('id', $attrIds)->orderBy('sort')->get()->toArray();

        $attrs = [];
        foreach ($goodsAttrs as $key=>$goodsAttr) {
            $attrs[] = [
                'label' => $goodsAttr['name'],
                'value' => $goodsAttrValues[$goodsAttr['id']]['value'],
            ];
        }

        $goodsInfo['attrs'] = $attrs;

        // 商品图片
        $images = GoodsImage::select(['img_url'])->where('goods_id', $goodsInfo['id'])->get()->toArray();

        foreach ($images as $key=>$image) {
            $images[$key]['img_url'] = full_url($image['img_url']);
        }

        $goodsInfo['imgs'] = array_column($images, 'img_url');

        if ($goodsInfo['type'] == Goods::TYPE_MULTI_SPEC) {
            $goodsSpecs = GoodsSpec::where('model_id', $goodsInfo['model_id'])->orderBy('sort')->get()->toArray();
            foreach ($goodsSpecs as $key=>$goodsSpec) {
                $values = explode(',', $goodsSpec['values']);

                $goodsInfo['specs'][] = [
                    'title' => $goodsSpec['name'],
                    'list' => $values
                ];
            }
        }

        $relation = GoodsTagRelation::where('goods_id', $goodsInfo['id'])->get()->toArray();
        $tagIds = array_column($relation, 'tag_id');
        $tags = GoodsTag::whereIn('id', $tagIds)->get()->toArray();
        $goodsInfo['tags'] = $tags;

        // 商品SKU
        $goodsSKU = self::getSKU($goodsInfo['id']);
        $goodsInfo['sku'] = $goodsSKU;

        // 商品活动
        $goodsInfo['activity'] = GoodsActivityService::getGoodsJoinActivity($goodsInfo);

        if ($goodsInfo['activity']) {
            self::setActivityPrice($goodsInfo);
        }

        $goodsInfo['can_add_cart'] = self::checkCanAddToCart($goodsInfo['id']);
        $goodsInfo['content'] = str_replace('src="', 'src="' . getenv('APP_URL'), $goodsInfo['content']);

        // 是否收藏
        $goodsInfo['is_collect'] = false;
        if (get_user_id()) {
            $goodsInfo['is_collect'] = UserCollectService::isCollect(UserCollect::GOODS, $goodsInfo['id']);

            UserHistoryService::add(UserHistory::GOODS, $goodsInfo['id']);
        }

        //评价信息
        ['all_count' => $goodsInfo['comment_count']] = GoodsCommentService::getCommentCount($goodsInfo['id']);
        $goodsInfo['good_comment_rate'] = GoodsCommentService::goodCommentRate($goodsInfo['id']);
        $goodsInfo['nice_comments'] = GoodsCommentService::getNiceComments($goodsInfo['id']);

        return $goodsInfo;
    }

    public static function setActivityPrice(&$goodsInfo, $cartItem)
    {
        $activity = $goodsInfo['activity'];

        if (!$activity) {
            return;
        }

        if ($activity['type'] == GoodsActivity::DISCOUNT) {
            $goodsInfo['market_price'] = $goodsInfo['price'];
            $goodsInfo['price'] = bcmul($goodsInfo['price'], bcdiv($activity['discount'], 100, 2), 2);
            $goodsInfo['preferential_price'] = bcsub($goodsInfo['market_price'], $goodsInfo['price'], 2);

            if ($goodsInfo['type'] == Goods::TYPE_MULTI_SPEC) {
                if (isset($goodsInfo['sku'][0])) {
                    foreach ($goodsInfo['sku'] as $key=>$skuItem) {
                        $skuItem['market_price'] = $skuItem['price'];
                        $skuItem['price'] = bcmul($skuItem['price'], bcdiv($activity['discount'], 100, 2), 2);
                        $skuItem['preferential_price'] = bcsub($skuItem['market_price'], $skuItem['price'], 2);
                        $goodsInfo['sku'][$key] = $skuItem;
                    }
                } else {
                    $goodsInfo['sku']['market_price'] = $goodsInfo['sku']['price'];
                    $goodsInfo['sku']['price'] = bcmul($goodsInfo['sku']['price'], bcdiv($activity['discount'], 100, 2), 2);
                    $goodsInfo['sku']['preferential_price'] = bcsub($goodsInfo['sku']['market_price'], $goodsInfo['sku']['price'], 2);
                }
            }
        } else {
            if (bcmul($goodsInfo['price'], $cartItem['count'], 2) >= $activity['full']) {
                $goodsInfo['market_price'] = $goodsInfo['price'];
                $goodsInfo['price'] = bcsub($goodsInfo['price'], $activity['reduce'], 2);
                $goodsInfo['preferential_price'] = $activity['reduce'];
            }

            if ($goodsInfo['type'] == Goods::TYPE_MULTI_SPEC) {
                if (isset($goodsInfo['sku'][0])) {
                    foreach ($goodsInfo['sku'] as $key=>$skuItem) {
                        if (bcmul($skuItem['price'], $cartItem['count'], 2) >= $activity['full']) {
                            $skuItem['market_price'] = $skuItem['price'];
                            $skuItem['price'] = bcsub($skuItem['price'], $activity['reduce'], 2);
                            $skuItem['preferential_price'] = $activity['reduce'];
                        }
                        $goodsInfo['sku'][$key] = $skuItem;
                    }
                } else {
                    if (bcmul($goodsInfo['sku']['price'], $cartItem['count'], 2) >= $activity['full']) {
                        $goodsInfo['sku']['market_price'] = $goodsInfo['sku']['price'];
                        $goodsInfo['sku']['price'] = bcsub($goodsInfo['sku']['price'], $activity['reduce'], 2);
                        $goodsInfo['sku']['preferential_price'] = $activity['reduce'];
                    }
                }
            }
        }
    }

    public static function isGift($id)
    {
        $goodsInfo = Goods::select(['id', 'is_gift'])->where('id', $id)->first();

        return $goodsInfo['is_gift'];
    }

    public static function isNormal($id)
    {
        $goodsInfo = Goods::select(['id', 'is_normal'])->where('id', $id)->first();

        return $goodsInfo['is_normal'];
    }

    public static function checkCanAddToCart($id, $type = Goods::TYPE_SINGLE_SPEC, &$res = '')
    {
        $goodsId = $id;

        if ($type == Goods::TYPE_MULTI_SPEC) {
            $goodsSKU = GoodsSKU::where('id', $id)->first();

            if (!$goodsSKU) {
                throw new \Exception('不存在的商品');
            }

            $goodsId = $goodsSKU['goods_id'];
        }

        if (self::isGift($goodsId)) {
            $res = '该商品是报单商品，不能加购物车';
            return false;
        }

        $activity = GoodsActivityService::valid();
        $goodsIds = GoodsActivityService::getActivityGoodsIds($activity);

        if ($activity && ($activity['is_all_goods'] || (isset($goodsIds) && count($goodsIds) && in_array($goodsId, $goodsIds)))) {
            $res = '该商品已参与' . $activity['name'] . ',无法添加到购物车';
            return false;
        }

        return true;
    }

    public static function getTags($goodsId)
    {
        $relation = GoodsTagRelation::where('goods_id', $goodsId)->get()->toArray();
        $tagIds = array_column($relation, 'tag_id');

        $tags = GoodsTag::whereIn('id', $tagIds)->get()->toArray();

        return $tags;
    }

    public static function getSKU($goodsId)
    {
        $goodsSKU = GoodsSKU::select(['id', 'sku', 'stock', 'price', 'thumb'])->where('goods_id', $goodsId)->get()->toArray();
        foreach ($goodsSKU as $key=>$value) {
            $goodsSKU[$key]['sku'] = json_decode($value['sku'], true);
            $goodsSKU[$key]['thumb'] = full_url($value['thumb']);
        }

        return $goodsSKU;
    }

    public static function hasStock($id, $count, $type = Goods::TYPE_MULTI_SPEC, &$stock = 0)
    {
        if ($type == Goods::TYPE_MULTI_SPEC) {
            $goodsSKU = GoodsSKU::select(['id', 'goods_id', 'sku', 'stock', 'price', 'thumb'])->where('id', $id)->first();

            if ($goodsSKU['stock'] == 0 || $goodsSKU['stock'] < $count) {
                $stock = $goodsSKU['stock'];
                return false;
            }
        } else {
            $goods = Goods::where('id', $id)->first();

            if ($goods['stock'] == 0 || $goods['stock'] < $count) {
                $stock = $goods['stock'];
                return false;
            }
        }

        return true;
    }

    public static function isValid($id, $count = 1, $type = Goods::TYPE_MULTI_SPEC, &$res = '')
    {
        $goodsId = $id;

        if ($type == Goods::TYPE_MULTI_SPEC) {
            $goodsSKU = GoodsSKU::select(['id', 'goods_id', 'sku', 'stock', 'price', 'thumb'])->where('id', $id)->first();

            if (!$goodsSKU) {
                $res = '不存在的商品';
                return false;
            }

            if ($goodsSKU['stock'] == 0 || $goodsSKU['stock'] < $count) {
                $res = '库存不足';
                return false;
            }

            $goodsId = $goodsSKU['goods_id'];
        }

        $goods = Goods::where('id', $goodsId)->first();

        if (!$goods) {
            $res = '商品已删除';
            return false;
        }

        if ($goods['type'] != $type) {
            $res = $goods['name'] . '是多规格商品,sku_id参数缺失';
            return false;
        }

        if (!$goods['is_up']) {
            $res = $goods['name'] . '已下架';
            return false;
        }

        if ($type == Goods::TYPE_SINGLE_SPEC) {
            if ($goods['stock'] == 0 || $goods['stock'] < $count) {
                $res = $goods['name'] . '库存不足';
                return false;
            }
        }

        return true;
    }

    public static function guessYouLikeList($page, $length = 10)
    {
        if (empty(get_user_id())) {
            return self::list($page, $length, ['sale_count', 'desc']);
        }

        $orders = Order::select(['order_no'])->where('user_id', get_user_id())->whereNotNull('pay_time')->whereNull('cancel_time')->get()->toArray();

        if (count($orders) == 0) {
            //没成功购买过东西
            return self::list($page, $length, ['sale_count', 'desc']);
        }

        $orderNos = array_column($orders, 'order_no');

        $goodsList = OrderGoods::whereIn('order_no', $orderNos)->get()->toArray();
        $goodsIds = array_column($goodsList, 'goods_id');

        $otherUserGoodsList = OrderGoods::whereIn('goods_id', $goodsIds)->whereNotIn('order_no', $orderNos)->get()->toArray();
        $otherUserIds = array_column($otherUserGoodsList, 'user_id');

        $otherUserBuyGoodsList = OrderGoods::whereIn('user_id', $otherUserIds)->whereNotIn('goods_id', $goodsIds)->get()->toArray();
        $otherUserBuyGoodsIds = array_unique(array_column($otherUserBuyGoodsList, 'goods_id'));

        if (count($otherUserBuyGoodsIds)) {
            return self::list($page, $length, ['sale_count', 'desc']);
        }

        return self::list($page, $length, ['id', 'desc'], 0, '', $otherUserBuyGoodsIds);

    }

    public static function addSaleCount($order)
    {
        $goodsList = OrderGoods::where('order_no', $order['order_no'])->get()->toArray();

        foreach ($goodsList as $goods) {
            Goods::where('id', $goods['goods_id'])->increment('sale_count', $goods['count']);
        }
    }

    public static function generateNo()
    {
        return 'G' . time() . random_int(1000, 9999);
    }
}